package com.yh.homestay.aop;


import com.yh.homestay.pojo.SysLog;
import com.yh.homestay.service.LogModelService;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

@Component
@Aspect
public class LogAopAction {

    @Autowired
    private LogModelService logModelService;

    private SysLog logModel = new SysLog();

    /**
     * @param
     * @Date: 2020/1/14 9:08
     * @Description: 切点pointcut，定义在何处切入
     * @return: void
     */
    @Pointcut("@annotation( com.yh.homestay.aop.SystemLog)")
    private void controllerMethodAspect() {

    }

    /**
     * @param pjp
     * @Date: 2020/1/14 9:09
     * @Description: 通知，定义在何时、通知什么
     * @return: java.lang.Object
     */
    @Around("controllerMethodAspect()")
    public Object runMethod(ProceedingJoinPoint pjp) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        // 获取当前登陆用户信息
        String uid = request.getParameter("uid");
        if (uid == null) {
            logModel.setLogAccessAccount("未获取到帐号");
        } else {
            logModel.setLogAccessAccount(uid);
        }
        // 拦截的实体类，就是当前正在执行的controller
        Object target = pjp.getTarget();
        // 拦截的方法名称。当前正在执行的方法
        String methodName = pjp.getSignature().getName();
        // 拦截的方法参数
        Object[] args = pjp.getArgs();
        // 拦截的放参数类型
        Signature sig = pjp.getSignature();
        MethodSignature msig = null;
        if (!(sig instanceof MethodSignature)) {
            throw new IllegalArgumentException("该注解只能用于方法");
        }
        msig = (MethodSignature) sig;
        Class[] parameterTypes = msig.getMethod().getParameterTypes();

        Object object = null;

        Method method = null;
        try {
            method = target.getClass().getMethod(methodName, parameterTypes);
        } catch (NoSuchMethodException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        } catch (SecurityException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        if (null != method) {
            // 判断是否包含自定义的注解，说明一下这里的SystemLog就是我自己自定义的注解
            if (method.isAnnotationPresent(SystemLog.class)) {
                SystemLog systemlog = method.getAnnotation(SystemLog.class);
                logModel.setLogAccessModule(systemlog.module());
                logModel.setLogAccessFun(systemlog.methods());
                logModel.setLogAccessIp(getIp(request));
                logModel.setLogAccessUrl(request.getRequestURI());

                try {
                    object = pjp.proceed();
                    logModel.setLogAccessResult("执行成功");
                } catch (Throwable e) {
                    // TODO Auto-generated catch block
                    logModel.setLogAccessResult("执行失败");

                }
            }

        }

        logModelService.insertLog(logModel);
        return object;

    }

    /**
     * 获取ip地址
     *
     * @param request
     * @return
     */
    private String getIp(HttpServletRequest request) {
        if (request.getHeader("x-forwarded-for") == null) {
            return request.getRemoteAddr();
        }
        return request.getHeader("x-forwarded-for");
    }

}
